//
// Created by syj on 2024/3/14.
//

#ifndef TRANSMIDDLE_LOGSTREAM_H
#define TRANSMIDDLE_LOGSTREAM_H

#include <memory>
#include <sstream>
#include <type_traits>

#include "middle/log/common/common.h"
#include "spdlog/spdlog.h"

namespace log
{
    class LogStream final {
    public:
        LogStream(std::shared_ptr<spdlog::logger> logger,
                  spdlog::level::level_enum level)
                : logger_(logger), level_(level) {};
        ~LogStream() { logger_->log(level_, stream_.str()); }

        LogStream(const LogStream &) = delete;
        LogStream &operator=(const LogStream &) = delete;
        LogStream(LogStream &&other) noexcept;
        LogStream &operator=(LogStream &&) = delete;

        template <class T>
        [[deprecated("Use fmt instead")]] LogStream &operator<<(T &&value) {
            stream_ << std::forward<T>(value);
            return *this;
        }

        [[deprecated("Use fmt instead")]] LogStream &operator<<(unsigned char value) {
            stream_ << std::to_string(value);
            return *this;
        }

        [[deprecated("Use fmt instead")]] LogStream &operator<<(char value) {
            stream_ << std::to_string(value);
            return *this;
        }

        [[deprecated("Use fmt instead")]] LogStream &operator<<(std::atomic_uint8_t const &value) {
            stream_ << std::to_string(value.load());
            return *this;
        }

        [[deprecated("Use fmt instead")]] LogStream &operator<<(std::atomic_int8_t const &value) {
            stream_ << std::to_string(value.load());
            return *this;
        }

    private:
        std::shared_ptr<spdlog::logger> logger_;
        spdlog::level::level_enum level_;

        std::stringstream stream_;
    };

}//namespace log

#endif //TRANSMIDDLE_LOGSTREAM_H
